package com.heatup.apt.management.pay;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.heatup.apt.management.util.ManageConfigPropertiesUtil;

/**
 * 微信退款 
 * 全额退款
 * @author jixiangyun
 * 2016年9月26日 下午7:29:42
 */
public class RefundUtil {
	
	private static Logger logger = LoggerFactory.getLogger(RefundUtil.class);
	
	/**
	 * main函数，实现非部署情况下退款（仅限于全额退款）
	 * @param args
	 */
	public static void main(String[] args) {
		wechatRefund("101473823274698",(new BigDecimal("0.1")));
		/*Map<String,Object> map = toXML(xml);
		System.out.println(map);*/
	}
	/**
	 * 退款函数，该方法可以对曾经部分退款的订单进行再次退款
	 * @param out_trade_no 商户订单号
	 * 
	 * @param total_fee1 退款对应的订单的总金额（以“元”为单位）
	 * @param refund_fee1 计划退款的金额（以“元”为单位）
	 * @return
	 */
	public static Map<String,Object> wechatRefund1(String out_trade_no,BigDecimal total_fee1,BigDecimal refund_fee1){
		logger.info("================================order refund  wechatRefund1 start ======================================== ");
		String out_refund_no = UUID.randomUUID().toString().substring(0, 32);// 退款单号
		int total_fee = total_fee1.multiply(new BigDecimal("100")).intValue();//订单的总金额,以分为单位
		int refund_fee = refund_fee1.multiply(new BigDecimal("100")).intValue();// 退款金额，以分为单位
		String nonce_str = UUID.randomUUID().toString().substring(0, 10);// 随机字符串
		//开发者ID
		String appid =String.valueOf(ManageConfigPropertiesUtil.get("wechat_appid")).trim();//"wx65db45e85c1be9c4";
		//appsecret
		String appsecret = String.valueOf(ManageConfigPropertiesUtil.get("wechat_appsecret")).trim();//"3816ac8f220a3e9150fbab7321064d45";
		String refund_account =String.valueOf(ManageConfigPropertiesUtil.get("wechat_refund_account")).trim();// "REFUND_SOURCE_RECHARGE_FUNDS";
		//商户号 
		String mch_id = String.valueOf(ManageConfigPropertiesUtil.get("wechat_mch_id")).trim();//"1369211002";
		String op_user_id = mch_id;//就是MCHID
		//商户号
		String partnerkey = String.valueOf(ManageConfigPropertiesUtil.get("wechat_partnerkey")).trim();//"youfang20161001youfang2016100101";
		SortedMap<String, String> packageParams = new TreeMap<String, String>();
		packageParams.put("appid", appid);
		packageParams.put("mch_id", mch_id);
		packageParams.put("nonce_str", nonce_str);
		packageParams.put("out_trade_no", out_trade_no);
		packageParams.put("out_refund_no", out_refund_no);
		packageParams.put("total_fee", total_fee+"");
		packageParams.put("refund_fee", refund_fee+"");
		packageParams.put("op_user_id", op_user_id);
		packageParams.put("refund_account",refund_account);
		RequestHandler reqHandler = new RequestHandler(null, null);
		reqHandler.init(appid, appsecret, partnerkey);
		String sign = reqHandler.createSign(packageParams);
		String xml = "<xml>" + 
				"<appid>" + appid + "</appid>" + 
				"<mch_id>" + mch_id + "</mch_id>" + 
				"<nonce_str>" + nonce_str + "</nonce_str>" + 
				"<sign><![CDATA[" + sign + "]]></sign>"	+ 
				"<out_trade_no>" + out_trade_no + "</out_trade_no>"	+ 
				"<out_refund_no>" + out_refund_no + "</out_refund_no>" + 
				"<total_fee>" + total_fee + "</total_fee>" + 
				"<refund_fee>" + refund_fee + "</refund_fee>" + 
				"<op_user_id>" + op_user_id + "</op_user_id>" + 
				"<refund_account>" + refund_account + "</refund_account>" + 
				"</xml>";
		String createOrderURL =String.valueOf(ManageConfigPropertiesUtil.get("wechat_order_refund_urL")).trim(); 
		Map<String,Object> mapData = null;
		try {
			String refundResult= ClientCustomSSL.doRefund(createOrderURL, xml);
			logger.info("================================order refund  wechatRefund1 refundResult: "+refundResult);
			mapData = toXML(refundResult);
			if("SUCCESS".equals(mapData.get("result_code"))){
				System.out.println("退款产生的json字符串："+"\n"+refundResult);
				return mapData;
			}else{
				return mapData;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("=================== order refund  wechatRefund1 error:"+e.toString()+e.getCause(),e);
		}
		logger.info("================================order refund  wechatRefund1 end ======================================== ");
		return mapData;
	}
	
	/**
	 * 该方法默认全额退款，但如果该订单曾经退款一部分，那么就不可使用该方法
	 * @param out_trade_no 商户订单号
	 * @param total_fee1 总的退款金额（以“元”为单位）
	 */
	public static void wechatRefund(String out_trade_no,BigDecimal total_fee1){
		Map<String,Object> mapData  = wechatRefund1(out_trade_no,total_fee1,total_fee1);
	}
	/**
	 * 将String格式的xml转换为map
	 * @param xml
	 * @return
	 */
	public static Map<String,Object> toXML(String xml){
		Map<String,Object> map = new HashMap<String, Object>();
		Document dom = null;
		try {
			dom = DocumentHelper.parseText(xml);
			Element root=dom.getRootElement();
			String return_code = root.element("return_code").getText();
			String return_msg = root.element("return_code").getText();
			String result_code = root.element("result_code").getText();
			map.put("return_code",return_code);
			map.put("return_msg",return_msg);
			map.put("result_code",result_code);
			if("FAIL".equals(result_code)){
				String err_code = root.element("err_code").getText();
				String err_code_des = root.element("err_code_des").getText();
				map.put("err_code",err_code);
				map.put("err_code_des",err_code_des);
				return map;
			}
			map.put("result_code",root.element("result_code").getText());
			map.put("transaction_id",root.element("transaction_id").getText());
			map.put("out_trade_no",root.element("out_trade_no").getText());
			map.put("out_refund_no",root.element("out_refund_no").getText());
			map.put("refund_id",root.element("refund_id").getText());
			map.put("refund_channel",root.element("refund_channel").getText());
			map.put("refund_fee",root.element("refund_fee").getText());
			map.put("coupon_refund_fee",root.element("coupon_refund_fee").getText());
			map.put("total_fee",root.element("total_fee").getText());
			map.put("cash_fee",root.element("cash_fee").getText());
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return  map;
	}
	
	
}
